﻿using System;
using System.ServiceModel;
using System.Windows;
using System.Xml.Linq;

namespace QuailDashboard.View.Views
{
    /// <summary>
    /// The error window for the quail dashboard
    /// </summary>
    public partial class ErrorWindow
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorWindow"/> class to show an exception.
        /// </summary>
        /// <param name="e">The exception.</param>
        public ErrorWindow(Exception e)
            : this("An unknown error was encountered. Please contact the Quail administrator for more information.", e)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorWindow"/> class to show an exception.
        /// </summary>
        /// <param name="message">the message</param>
        /// <param name="e">The exception.</param>
        public ErrorWindow(string message, Exception e)
            : this(message, MessageFromException(e))
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorWindow"/> class to show a message for a missing Uri.
        /// </summary>
        /// <param name="uri">the Uri that was missing</param>
        public ErrorWindow(Uri uri)
            : this("An error with a Uri was encountered.  Please contact the Quail administrator for more information.",
                   "Page not found: \"" + uri + "\"")
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorWindow"/> class to show a generic message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="details">The details.</param>
        public ErrorWindow(string message, string details)
        {
            InitializeComponent();
            IntroductoryText.Text = message;
            ErrorTextBox.Text = details;
        }

        private static string MessageFromException(Exception anException)
        {
            try
            {
                var root = new XElement("Exception");
                var node = root;
                var e = anException;

                var fe = anException as FaultException<ExceptionDetail>;
                if (fe != null)
                {
                    var ed = fe.Detail;

                    while (ed != null)
                    {
                        node.Add(new XElement("Message", new XText(ed.Message)));
                        node.Add(new XElement("StackTrace", new XText(ed.StackTrace)));

                        ed = ed.InnerException;
                        if (ed != null)
                        {
                            var cnode = new XElement("InnerException");
                            node.Add(cnode);
                            node = cnode;
                        }
                    }
                }
                else
                {

                    while (e != null)
                    {
                        node.Add(new XElement("Message", new XText(e.Message)));
                        node.Add(new XElement("StackTrace", new XText(e.StackTrace)));

                        e = e.InnerException;
                        if (e != null)
                        {
                            var cnode = new XElement("InnerException");
                            node.Add(cnode);
                            node = cnode;
                        }
                    }
                }

                return new XDocument(root).ToString(SaveOptions.OmitDuplicateNamespaces);
            }
            catch (Exception e2)
            {
                return "Exception processing exception: " + e2.Message + "\nOriginal error: " + anException.Message;
            }
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
        }
    }
}